<template>
  <div class="message" :class="{ 'message-user': isUser }">
    <div class="avatar">
      <UserCircleIcon v-if="isUser" class="icon" />
      <ComputerDesktopIcon v-else class="icon" :class="{ 'assistant': !isUser }" />
    </div>
    <div class="content">
      <div class="text" ref="contentRef" v-if="isUser">
        {{ message.content }}
      </div>
      <div 
        class="text markdown-content" 
        ref="contentRef" 
        v-else 
        v-html="processedContent"
      ></div>
      <div class="time">{{ formatTime(message.timestamp) }}</div>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, nextTick, ref, watch } from 'vue'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { UserCircleIcon, ComputerDesktopIcon } from '@heroicons/vue/24/outline'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'

const contentRef = ref(null)

// 配置 marked - 保持简单
marked.setOptions({
  breaks: true,
  gfm: true,
  sanitize: false
})

const props = defineProps({
  message: {
    type: Object,
    required: true
  }
})

const isUser = computed(() => props.message.role === 'user')

const processedContent = computed(() => {
  if (!props.message.content) return ''
  
  let content = props.message.content
  
  // 处理 think 标签
  content = content.replace(
    /<think>(.*?)<\/think>/gs,
    '<div class="think-block">$1</div>'
  )
  
  // 转换 Markdown 为 HTML
  content = marked.parse(content)
  
  // 净化 HTML
  return DOMPurify.sanitize(content, {
    ADD_TAGS: ['think', 'code', 'pre', 'span'],
    ADD_ATTR: ['class', 'language']
  })
})

// 在内容更新后手动应用高亮
const highlightCode = async () => {
  await nextTick()
  if (contentRef.value) {
    contentRef.value.querySelectorAll('pre code').forEach((block) => {
      hljs.highlightElement(block)
    })
  }
}

// 监听内容变化
watch(() => props.message.content, () => {
  if (!isUser.value) {
    highlightCode()
  }
})

// 初始化时也执行一次
onMounted(() => {
  if (!isUser.value) {
    highlightCode()
  }
})

const formatTime = (timestamp) => {
  if (!timestamp) return ''
  return new Date(timestamp).toLocaleTimeString()
}
</script>

<style scoped lang="scss">
.message {
  display: flex;
  margin-bottom: 1.5rem;
  gap: 1rem;
  
  &.message-user {
    flex-direction: row-reverse;
    
    .content {
      align-items: flex-end;
      
      .text {
        background: #007CF0;
        color: white;
        border-radius: 1rem 1rem 0 1rem;
      }
    }
  }

  .avatar {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    
    .icon {
      width: 100%;
      height: 100%;
      color: #666;
      padding: 4px;
      border-radius: 8px;
      transition: all 0.3s ease;

      &.assistant {
        color: #333;
        background: #f0f0f0;
        
        &:hover {
          background: #e0e0e0;
          transform: scale(1.05);
        }
      }
    }
  }

  .content {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-width: 80%;
    
    .text {
      padding: 1rem;
      border-radius: 1rem 1rem 1rem 0;
      line-height: 1.5;
      white-space: pre-wrap;
      color: var(--text-color);
      
      .cursor {
        animation: blink 1s infinite;
      }

      :deep(.think-block) {
        position: relative;
        padding: 0.75rem 1rem 0.75rem 1.5rem;
        margin: 0.5rem 0;
        color: #666;
        font-style: italic;
        border-left: 4px solid #ddd;
        background-color: rgba(0, 0, 0, 0.03);
        border-radius: 0 0.5rem 0.5rem 0;

        &::before {
          content: '思考';
          position: absolute;
          top: -0.75rem;
          left: 1rem;
          padding: 0 0.5rem;
          font-size: 0.75rem;
          background: #f5f5f5;
          border-radius: 0.25rem;
          color: #999;
          font-style: normal;
        }
      }

      :deep(pre) {
        background: #f6f8fa;
        padding: 1rem;
        border-radius: 0.5rem;
        overflow-x: auto;
        margin: 0.5rem 0;
        border: 1px solid #e1e4e8;

        code {
          background: transparent;
          padding: 0;
          font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
          font-size: 0.9rem;
          line-height: 1.5;
          tab-size: 2;
        }
      }

      :deep(.hljs) {
        color: #24292e;
        background: transparent;
      }

      :deep(.hljs-keyword) { color: #d73a49; }
      :deep(.hljs-built_in) { color: #005cc5; }
      :deep(.hljs-type) { color: #6f42c1; }
      :deep(.hljs-literal) { color: #005cc5; }
      :deep(.hljs-number) { color: #005cc5; }
      :deep(.hljs-regexp) { color: #032f62; }
      :deep(.hljs-string) { color: #032f62; }
      :deep(.hljs-subst) { color: #24292e; }
      :deep(.hljs-symbol) { color: #e36209; }
      :deep(.hljs-class) { color: #6f42c1; }
      :deep(.hljs-function) { color: #6f42c1; }
      :deep(.hljs-title) { color: #6f42c1; }
      :deep(.hljs-params) { color: #24292e; }
      :deep(.hljs-comment) { color: #6a737d; }
      :deep(.hljs-doctag) { color: #d73a49; }
      :deep(.hljs-meta) { color: #6a737d; }
      :deep(.hljs-section) { color: #005cc5; }
      :deep(.hljs-name) { color: #22863a; }
      :deep(.hljs-attribute) { color: #005cc5; }
      :deep(.hljs-variable) { color: #e36209; }
    }
    
    .time {
      font-size: 0.75rem;
      color: #666;
    }
  }
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

.dark {
  .message {
    .avatar .icon {
      &.assistant {
        color: #fff;
        background: #444;
        
        &:hover {
          background: #555;
        }
      }
    }
    
    .content {
      .text {
        :deep(.think-block) {
          background-color: rgba(255, 255, 255, 0.03);
          border-left-color: #666;
          color: #999;

          &::before {
            background: #2a2a2a;
            color: #888;
          }
        }

        :deep(pre) {
          background: #161b22;
          border-color: #30363d;
          
          code {
            color: #c9d1d9;
          }
        }

        :deep(.hljs) {
          color: #c9d1d9;
          background: transparent;
        }

        :deep(.hljs-keyword) { color: #ff7b72; }
        :deep(.hljs-built_in) { color: #79c0ff; }
        :deep(.hljs-type) { color: #ff7b72; }
        :deep(.hljs-literal) { color: #79c0ff; }
        :deep(.hljs-number) { color: #79c0ff; }
        :deep(.hljs-regexp) { color: #a5d6ff; }
        :deep(.hljs-string) { color: #a5d6ff; }
        :deep(.hljs-subst) { color: #c9d1d9; }
        :deep(.hljs-symbol) { color: #ffa657; }
        :deep(.hljs-class) { color: #f2cc60; }
        :deep(.hljs-function) { color: #d2a8ff; }
        :deep(.hljs-title) { color: #d2a8ff; }
        :deep(.hljs-params) { color: #c9d1d9; }
        :deep(.hljs-comment) { color: #8b949e; }
        :deep(.hljs-doctag) { color: #ff7b72; }
        :deep(.hljs-meta) { color: #8b949e; }
        :deep(.hljs-section) { color: #79c0ff; }
        :deep(.hljs-name) { color: #7ee787; }
        :deep(.hljs-attribute) { color: #79c0ff; }
        :deep(.hljs-variable) { color: #ffa657; }
      }
      
      .time {
        color: #999;
      }
    }
    
    &.message-user .content .text {
      background: #0066cc;
      color: white;
    }
  }
}

.markdown-content {
  :deep(p) {
    margin: 0.5rem 0;
    &:first-child { margin-top: 0; }
    &:last-child { margin-bottom: 0; }
  }

  :deep(ul), :deep(ol) {
    margin: 0.5rem 0;
    padding-left: 1.5rem;
  }

  :deep(li) {
    margin: 0.25rem 0;
  }

  :deep(code) {
    background: rgba(0, 0, 0, 0.05);
    padding: 0.2em 0.4em;
    border-radius: 3px;
    font-size: 0.9em;
    font-family: ui-monospace, monospace;
  }

  :deep(pre code) {
    background: transparent;
    padding: 0;
  }

  :deep(table) {
    border-collapse: collapse;
    margin: 0.5rem 0;
    width: 100%;
  }

  :deep(th), :deep(td) {
    border: 1px solid #ddd;
    padding: 0.5rem;
    text-align: left;
  }

  :deep(th) {
    background: rgba(0, 0, 0, 0.05);
  }

  :deep(blockquote) {
    margin: 0.5rem 0;
    padding-left: 1rem;
    border-left: 4px solid #ddd;
    color: #666;
  }
}

.dark {
  .markdown-content {
    :deep(code) {
      background: rgba(255, 255, 255, 0.1);
    }

    :deep(th), :deep(td) {
      border-color: #444;
    }

    :deep(th) {
      background: rgba(255, 255, 255, 0.1);
    }

    :deep(blockquote) {
      border-left-color: #444;
      color: #999;
    }
  }
}
</style> 